home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_pcdp / ada / ds.ada < prev    next >
Text File  |  1996-01-30  |  5KB  |  190 lines

  1. with Semaphore_Package; use Semaphore_Package;
  2. with Text_IO; use Text_IO; 
  3. procedure DS is
  4.  
  5.   type Node_Count is range 0..4;
  6.   subtype Node_ID is Node_Count range 1..Node_Count'Last;
  7.  
  8.   task type Nodes is
  9.     entry Init(ID: Node_ID; N_I, N_O: Node_Count);
  10.     entry Configure(C: Node_ID);
  11.     entry Message(M: Integer; ID: Node_ID);
  12.     entry Signal(ID: Node_ID);
  13.   end Nodes;
  14.  
  15.   Node: array(Node_ID) of Nodes;
  16.  
  17.   task body Nodes is
  18.  
  19.     type Edge is
  20.       record
  21.         Exists:  Boolean := False;
  22.         Deficit: Natural := 0;
  23.       end record;
  24.  
  25.     Incoming: array(Node_ID) of Edge;
  26.     Outgoing: array(Node_ID) of Edge;
  27.     First_Edge:  Node_Count := 0;
  28.     N_In, N_Out: Node_Count := 0;
  29.     N_Signals:   Natural := 0;
  30.  
  31.     pragma Volatile(N_Signals);
  32.     pragma Volatile(First_Edge);
  33.     pragma Volatile(Incoming);
  34.  
  35.     I: Node_ID;
  36.     S: Binary_Semaphore := Init(1);
  37.     Received_ID: Node_ID;
  38.  
  39.     task Main_Process is
  40.       entry Init;
  41.     end Main_Process;
  42.  
  43.     task body Main_Process is
  44.       Count: Integer := 0;
  45.  
  46.       procedure Send_Messages is
  47.       begin
  48.         for J in Node_ID loop
  49.           if Outgoing(J).Exists then
  50.              Put_Line("  " & Node_ID'Image(I) & " sending  " &
  51.                      Integer'Image(Count) & " to   " &
  52.                      Node_ID'Image(J));
  53.              Wait(S);
  54.              N_Signals := N_Signals + 1;
  55.              Signal(S);
  56.              Node(J).Message(Count, I);
  57.           end if;
  58.         end loop;
  59.       end Send_Messages;
  60.  
  61.       function Decide_to_Terminate return Boolean is
  62.  
  63.         procedure Send_Signals(ID: Node_ID) is
  64.         begin
  65.           while Incoming(ID).Deficit > 0 loop
  66.             Incoming(ID).Deficit := Incoming(ID).Deficit - 1;
  67.             Put_Line("  " & Node_ID'Image(I) & " sending signal to " &
  68.                      Node_ID'Image(ID));
  69.             Signal(S);
  70.             Node(ID).Signal(I);
  71.             Wait(S);
  72.           end loop;
  73.         end Send_Signals;
  74.  
  75.       begin
  76.         for J in Node_ID loop
  77.           if  J /= First_Edge then
  78.             Wait(S);
  79.             Send_Signals(J);
  80.             Signal(S);
  81.           end if;
  82.         end loop;
  83.  
  84.         Wait(S);
  85.         if N_Signals = 0 then
  86.           if I = 1 then
  87.             Put_Line("  " & Node_ID'Image(I) & " program terminated ");
  88.           elsif First_Edge /= 0 then
  89.             Send_Signals(First_Edge);
  90.             First_Edge := 0;
  91.           end if;
  92.           Signal(S);
  93.           return True;
  94.         else 
  95.           Signal(S);
  96.           return False;
  97.         end if;
  98.       end Decide_to_Terminate;
  99.  
  100.     begin
  101.       accept Init;
  102.       if I = 1 then 
  103.         Send_Messages;
  104.         Send_Messages;
  105.         loop
  106.           exit when Decide_to_Terminate;
  107.           delay 0.01;
  108.         end loop;
  109.       else
  110.         loop
  111.           loop 
  112.             exit when First_Edge /= 0;
  113.             delay 0.01;
  114.           end loop;
  115.           if Count < 5 then
  116.             Count := Count + 1;
  117.             Send_Messages;
  118.           end if;
  119.           loop
  120.             exit when not Decide_to_Terminate or First_Edge /= 0;
  121.             delay 0.01;
  122.           end loop;
  123.         end loop;
  124.       end if;
  125.     end Main_Process;
  126.  
  127.   begin
  128.     accept Init(ID: Node_ID; N_I, N_O: Node_Count) do
  129.       I := ID;
  130.       N_In  := N_I;
  131.       N_Out := N_O;
  132.     end Init;
  133.     for J in 1..N_In loop
  134.       accept Configure(C: Node_ID) do
  135.         Incoming(C).Exists := True;
  136.       end Configure;
  137.     end loop;
  138.     for J in 1..N_Out loop
  139.       accept Configure(C: Node_ID) do
  140.         Outgoing(C).Exists := True;
  141.       end Configure;
  142.     end loop;
  143.  
  144.     Main_Process.Init;
  145.  
  146.     loop
  147.       select 
  148.         accept Message(M: Integer; ID: Node_ID) do
  149.           Put_Line("  " & Node_ID'Image(I) & " received " &
  150.                    Integer'Image(M) & " from " &
  151.                    Node_ID'Image(ID));
  152.           Received_ID := ID;
  153.         end Message;
  154.         if First_Edge = 0 then
  155.           First_Edge := Received_ID;
  156.         end if;
  157.         Wait(S);
  158.         Incoming(Received_ID).Deficit := Incoming(Received_ID).Deficit + 1;
  159.         Signal(S);
  160.       or
  161.         accept Signal(ID: Node_ID) do
  162.           Put_Line("  " & Node_ID'Image(I) & " received signal from " &
  163.                    Node_ID'Image(ID));
  164.           Received_ID := ID;
  165.         end Signal;
  166.         Wait(S);
  167.         N_Signals := N_Signals - 1;
  168.         Signal(S);
  169.       or
  170.         terminate;
  171.       end select;
  172.     end loop;
  173.   end Nodes;
  174.  
  175. begin
  176.   Node(1).Init(1,0,2); 
  177.   Node(1).Configure(2); Node(1).Configure(3);
  178.  
  179.   Node(2).Init(2,2,2); 
  180.   Node(2).Configure(1); Node(2).Configure(3);
  181.   Node(2).Configure(3); Node(2).Configure(4);
  182.  
  183.   Node(3).Init(3,3,1); 
  184.   Node(3).Configure(1); Node(3).Configure(2);
  185.   Node(3).Configure(4); Node(3).Configure(2);
  186.  
  187.   Node(4).Init(4,1,1); 
  188.   Node(4).Configure(2); Node(4).Configure(3);
  189. end DS;
  190.